package cn.group7.padserver.filter;

import cn.group7.padserver.entity.AuthenticationBean;
import com.alibaba.fastjson2.JSON;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author 谷汉斌
 * @description 自定义认证（登录）过滤器
 * @createTime 2024/7/31 下午4:43
 */
@Slf4j
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {
        log.info("开始执行CustomAuthenticationFilter*************");
        //获取请求头，据此判断请求参数类型
        String contentType = request.getContentType();
        if (MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(contentType)) {
            //说明请求参数是 JSON
            if (!"POST".equals(request.getMethod())) {
                throw new AuthenticationServiceException("不支持的登录请求方式！" + request.getMethod());
            }
            //提取用户名和密码
            String userName;
            String password;
            //构建登录令牌
            UsernamePasswordAuthenticationToken authRequest;
            try (InputStream is = request.getInputStream()) {
                //解析请求体中的 JSON 参数
                AuthenticationBean authenticationBean = JSON.parseObject(is.readAllBytes(), AuthenticationBean.class);
                userName = authenticationBean.getUsername();
                userName = (userName != null) ? userName.trim() : "";
                password = authenticationBean.getPassword();
                password = (password != null) ? password : "";
                log.info("尝试登录的用户信息【用户名：{},密码：{}】", userName, password);
                authRequest = UsernamePasswordAuthenticationToken.unauthenticated(userName, password);
            } catch (IOException e) {
                log.error("登录请求体解析失败！", e);
                authRequest = new UsernamePasswordAuthenticationToken(
                        "", "");
            }
            // 调用setDetails方法设置登录详情
            // Allow subclasses to set the "details" property
            setDetails(request, authRequest);
            log.info("开始验权...");
            //通过getAuthenticationManager()获取认证管理器，并调用authenticate方法进行认证，返回认证结果。
            Authentication authentication = this.getAuthenticationManager().authenticate(authRequest);
            log.info("验权结果{}", authentication.isAuthenticated());
            return authentication;
        } else {
            //不是JSON类型调用父类的attemptAuthentication方法处理
            return super.attemptAuthentication(request, response);
        }
    }
}
